package containers

import (
	"com.yy.api/common/utils"
	"context"
	"fmt"
	"github.com/containers/podman/v4/pkg/bindings/containers"
	"github.com/containers/podman/v4/pkg/domain/entities"
)

func newHostPortStrMap(hostPort string) strMap {
	return strMap{
		tag: hostPort,
		val: "used",
	}
}

func newNvidiaGpuStrMap(gpuId int) strMap {
	return strMap{
		tag: fmt.Sprintf("%s%d", NVIDIA_GPU_PATH, gpuId),
		val: "used",
	}
}

type filter struct {
	ID     []string
	Status []string
	Labels []strMap
	Name   []string
}

func (f *filter) toMap() map[string][]string {
	var m = map[string][]string{}
	if f.ID != nil && len(f.ID) > 0 {
		m["id"] = f.ID
	}
	if f.Status != nil && len(f.Status) > 0 {
		m["status"] = f.Status
	}
	if f.Name != nil && len(f.Name) > 0 {
		m["name"] = f.Name
	}
	if f.Labels != nil && len(f.Labels) > 0 {
		m["label"] = []string{}
		for _, l := range f.Labels {
			m["label"] = append(m["label"], l.String())
		}
	}
	return m
}

type ListOptionBuilder struct {
	options *containers.ListOptions
	*filter
}

func NewListOptionBuilder() *ListOptionBuilder {
	return &ListOptionBuilder{
		options: &containers.ListOptions{
			All:     utils.BaseTypeToPtr(true),
			Size:    utils.BaseTypeToPtr(true),
			Filters: map[string][]string{},
		},
		filter: &filter{
			ID:     []string{},
			Status: []string{},
			Labels: []strMap{},
			Name:   []string{},
		},
	}
}

// "id:b19819872nkd8"
func (ob *ListOptionBuilder) AddContainerId(containerId string) {
	ob.filter.ID = append(ob.filter.ID, containerId)
}

// "22014:used"
func (ob *ListOptionBuilder) AddHostPort(hostPort string) {
	ob.filter.Labels = append(ob.filter.Labels, newHostPortStrMap(hostPort))
}

// "/dev/nvidia0:used"
func (ob *ListOptionBuilder) AddGpuId(gpuId int) {
	ob.filter.Labels = append(ob.filter.Labels, newNvidiaGpuStrMap(gpuId))
}

// "user_id:082739071"
func (ob *ListOptionBuilder) AddUserId(userId string) {
	ob.filter.Labels = append(ob.filter.Labels, strMap{
		tag: "user_id",
		val: userId,
	})
}

// "display_id:082739071"
func (ob *ListOptionBuilder) AddDisplayId(displayId string) {
	ob.filter.Labels = append(ob.filter.Labels, strMap{
		tag: "display_id",
		val: displayId,
	})
}

// "status:running" 可搜集多种状态 running,exited
func (ob *ListOptionBuilder) AddStatus(status ...string) {
	for _, s := range status {
		ob.filter.Status = append(ob.filter.Status, s)
	}
}
func (ob *ListOptionBuilder) generate() *containers.ListOptions {
	ob.options.Filters = ob.filter.toMap()
	return ob.options
}
func (ob *ListOptionBuilder) List(ctx context.Context) ([]entities.ListContainer, error) {
	return containers.List(ctx, ob.generate())
}
